package com.zsc.shixun.service.function.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zsc.shixun.contant.Contant;
import com.zsc.shixun.entity.Article;
import com.zsc.shixun.entity.Comment;
import com.zsc.shixun.entity.User;
import com.zsc.shixun.model.data.DataVO;
import com.zsc.shixun.service.IArticleService;
import com.zsc.shixun.service.ICommentService;
import com.zsc.shixun.service.IUserService;
import com.zsc.shixun.service.function.DataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 数据观星
 * </p>
 *
 * @author ZWYZY
 * @since 2020/6/16
 */
@Service
@Transactional
public class DataServiceImpl implements DataService {
    @Autowired
    public IUserService userService;
    @Autowired
    public IArticleService articleService;

    @Autowired
    public ICommentService commentService;
    @Autowired
    public RedisTemplate redisTemplate;

    public static Calendar min;
    public static Calendar max;
    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

//    static {
//        handleDateData();
//    }

    @Override
    public DataVO getDataByAdmin() {
        if (redisTemplate.hasKey(Contant.DATA_ADMIN_KEY)) {
            return (DataVO) redisTemplate.opsForValue().get(Contant.DATA_ADMIN_KEY);
        }

        DataVO dataVO = new DataVO();
        dataVO.setArticleNumber(Long.valueOf(articleService.count()));
        dataVO.setCommentNumber(Long.valueOf(commentService.count()));
        dataVO.setClickNumber(articleService.list().stream().mapToLong(Article::getClickNumber).sum());
        dataVO.setLikeNumber(articleService.list().stream().mapToLong(Article::getLikeNumber).sum());
        dataVO.setDate(getDateShow());
        dataVO.setCommentTotal(getCommentTotal());
        dataVO.setArticleTotal(getAtricleTotal());
        redisTemplate.opsForValue().set(Contant.DATA_ADMIN_KEY, dataVO);
        return dataVO;
    }

    @Override
    public DataVO getDataByCommon(Long id) {
        if (redisTemplate.hasKey(Contant.DATA_COMMON_KEY + id)) {
            return (DataVO) redisTemplate.opsForValue().get(Contant.DATA_COMMON_KEY + id);
        }
        DataVO dataVO = new DataVO();
        User user = userService.getById(id);
        QueryWrapper<Article> queryWrapper = new QueryWrapper<Article>().eq("user_id", id);
        Integer articleNumber = articleService.count(queryWrapper);
        dataVO.setArticleNumber(Long.parseLong(articleNumber.toString()));
        List<Article> articleList = articleService.list(queryWrapper);
        dataVO.setLikeNumber(articleList.stream().mapToLong(Article::getLikeNumber).sum());
        dataVO.setCommentNumber(articleList.stream().mapToLong(Article::getCommentNumber).sum());
        dataVO.setClickNumber(articleList.stream().mapToLong(Article::getClickNumber).sum());
        dataVO.setArticleTotal(getAtricleTotal(id));
        dataVO.setCommentTotal(getCommentTotal(id));
        dataVO.setDate(getDateShow());
        redisTemplate.opsForValue().set(Contant.DATA_COMMON_KEY + id, dataVO);
        return dataVO;
    }

    @Override
    public List<Integer> getAtricleTotal(Long id) {
        handleDateData();

        List<Integer> articleTotal = new ArrayList<>(10);
        ArrayList<Date> dateArrayList = getDate();
        for (int i = 0; i < dateArrayList.size() - 1; i++) {
            int count = articleService.count(new QueryWrapper<Article>().lambda().eq(Article::getUserId, id).between(Article::getCreateTime, dateArrayList.get(i), dateArrayList.get(i + 1)));
            articleTotal.add(count);
        }
        return articleTotal;
    }

    @Override
    public List<Integer> getCommentTotal(Long id) {
        handleDateData();

        List<Integer> commentTotal = new ArrayList<>(10);
        ArrayList<Date> dateArrayList = getDate();
        for (int i = 0; i < dateArrayList.size() - 1; i++) {
            int count = commentService.count(new QueryWrapper<Comment>().lambda().eq(Comment::getUserId, id).between(Comment::getCreateTime, dateArrayList.get(i), dateArrayList.get(i + 1)));
            commentTotal.add(count);
        }
        return commentTotal;
    }

    @Override
    public List<Integer> getAtricleTotal() {
        handleDateData();
        List<Integer> articleTotal = new ArrayList<>(10);
        ArrayList<Date> dateArrayList = getDate();
        for (int i = 0; i < dateArrayList.size() - 1; i++) {
            int count = articleService.count(new QueryWrapper<Article>().lambda().between(Article::getCreateTime, dateArrayList.get(i), dateArrayList.get(i + 1)));
            articleTotal.add(count);
        }
        return articleTotal;
    }

    @Override
    public List<Integer> getCommentTotal() {
        handleDateData();
        List<Integer> commentTotal = new ArrayList<>(10);
        ArrayList<Date> dateArrayList = getDate();
        for (int i = 0; i < dateArrayList.size() - 1; i++) {
            int count = commentService.count(new QueryWrapper<Comment>().lambda().between(Comment::getCreateTime, dateArrayList.get(i), dateArrayList.get(i + 1)));
            commentTotal.add(count);
        }
        return commentTotal;
    }


    @Override
    public ArrayList<Date> getDate() {
        ArrayList<Date> result = new ArrayList<Date>(10);
        Calendar curr = min;
        while (curr.before(max)) {
            result.add(curr.getTime());
            curr.add(Calendar.MONTH, 1);
        }
        System.out.println(result);
        return result;

    }

    @Override
    public ArrayList<String> getDateShow() {
        handleDateData();
        ArrayList<String> result = new ArrayList<String>(10);
        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }
        System.out.println(result);
        return result;
    }


    public static void handleDateData() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -5);
        //六个月前
        String before_six = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH);
        ArrayList<Date> result = new ArrayList<Date>(10);
        // 格式化为年月
        min = Calendar.getInstance();
        max = Calendar.getInstance();
        try {
            min.setTime(sdf.parse(before_six));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
        try {
            max.setTime(sdf.parse(sdf.format(new Date())));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
    }
}
